using System;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Permissions;
using Microsoft.Win32.SafeHandles;

namespace AduSkin.Controls.Tools.Interop
{
   internal sealed class SafeFileMappingHandle : SafeHandleZeroOrMinusOneIsInvalid
   {
      [SecurityCritical]
      internal SafeFileMappingHandle(IntPtr handle) : base(false)
      {
         SetHandle(handle);
      }

      [SecurityCritical, SecuritySafeCritical]
      internal SafeFileMappingHandle() : base(true)
      {
      }

      public override bool IsInvalid
      {
         [SecurityCritical, SecuritySafeCritical]
         get => handle == IntPtr.Zero;
      }

      [SecurityCritical, SecuritySafeCritical]
      protected override bool ReleaseHandle()
      {
         new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Assert();
         try
         {
            return CloseHandleNoThrow(new HandleRef(null, handle));
         }
         finally
         {
            CodeAccessPermission.RevertAssert();
         }
      }

      [SecurityCritical]
      public static bool CloseHandleNoThrow(HandleRef handle)
      {
         HandleCollector.Remove((IntPtr)handle, CommonHandles.Kernel);
         var result = InteropMethods.IntCloseHandle(handle);
         return result;
      }
   }
}
